package cn.xiaobai.listener;

import cn.xiaobai.constants.CustomKeyConstants;
import cn.xiaobai.domain.CustomHotKeyModel;
import cn.xiaobai.domain.HotModel;
import cn.xiaobai.domain.KeyAdapterModel;
import cn.xiaobai.enums.ModHotKeyEnum;
import cn.xiaobai.enums.RobotKeyEnum;
import cn.xiaobai.service.HotKeyCustomService;
import cn.xiaobai.service.IClipboardService;
import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author yangdaji
 * @Date 2022/10/11 1011
 * @PackageName com.supconit.suptap.gateway.xiaobai.listener
 * @ClassName GlobalKeyListener
 */
@Slf4j
public class GlobalKeyListener {

    private Robot robot;

    private HotkeyListener hotkeyListener;

    private JIntellitype jIntellitypeInstance;

    @Autowired
    private IClipboardService cclipboardService;

    private String filePath;

    /**
     * 普通键地图, key: identifier value: CustomKeyConstants keycode
     */
    private Map<Integer, String> hotkeyMap = new ConcurrentHashMap<>(6);
    /**
     * 功能键地图, key: identifier value: CustomKeyConstants keycode
     */
    private Map<Integer, String> modHotkeyMap = new ConcurrentHashMap<>(6);

    /**
     * 键适配映射
     */
    private Map<String, Integer> keyAdapterMap;

    public GlobalKeyListener(Robot robot, JIntellitype jIntellitypeInstance, HotKeyCustomService hotKeyCustomService,
                             KeyAdapterModel keyAdapterModel) {
        this.robot = robot;
        this.jIntellitypeInstance = jIntellitypeInstance;
        keyAdapterMap = keyAdapterModel.getKeyAdapterMap();
        Optional<HotModel> hotModel = hotKeyCustomService.getHotModel();
        if (hotModel.isPresent()) {
            HotModel model = hotModel.get();
            filePath = model.getFilePath();
            customHotKey(model.getCustomHotKey());
        }
    }

    /**
     * 自定义热键设置
     *
     * @param customHotKey 热键
     */
    private void customHotKey(List<CustomHotKeyModel> customHotKey) {
        if (CollectionUtils.isEmpty(customHotKey)) {
            // 使用默认
            addKey();
            addKeyEvent();
        } else {
            for (CustomHotKeyModel customHotKeyModel : customHotKey) {
                Integer identifier = customHotKeyModel.getIdentifier();
                if (Boolean.TRUE.equals(customHotKeyModel.getOverride())) {
                    String combinationKey = customHotKeyModel.getKey();
                    String[] split = combinationKey.split("\\+");
                    if (split.length >= 2) {
                        addKey(customHotKeyModel.getIdentifier(), split[0], split[1]);
                    }
                } else {
                    // 不覆盖使用默认
                    addKey(identifier);
                }
            }
            addKeyEvent();
        }

    }


    /**
     * 注册默认热键 ( ctrl + c, ctrl+insert)
     */
    public void addKey() {
        jIntellitypeInstance.registerHotKey(1, JIntellitype.MOD_CONTROL, CustomKeyConstants.VK_C);
        jIntellitypeInstance.registerHotKey(2, JIntellitype.MOD_CONTROL, CustomKeyConstants.VK_X);
        jIntellitypeInstance.registerHotKey(3, JIntellitype.MOD_CONTROL, CustomKeyConstants.MOD_INSERT);
    }

    /**
     * 注册指定热键
     *
     * @param keyId
     */
    public void addKey(int keyId) {
        switch (keyId) {
            case 1:
                jIntellitypeInstance.registerHotKey(keyId, JIntellitype.MOD_CONTROL, CustomKeyConstants.VK_C);
                break;
            case 2:
                jIntellitypeInstance.registerHotKey(keyId, JIntellitype.MOD_CONTROL, CustomKeyConstants.VK_X);
                break;
            case 3:
                jIntellitypeInstance.registerHotKey(keyId, JIntellitype.MOD_CONTROL, CustomKeyConstants.MOD_INSERT);
                break;
            default:
                break;
        }

    }


    /**
     * 自定义热键 使用功能键+键进行组合
     *
     * @param identifier 键id
     * @param modifier   功能键(0表示不使用) 来自: com.melloware.jintellitype.JIntellitypeConstants
     * @param keName     键名称
     */
    public void addKey(int identifier, String modifier, String keName) {
        Integer keycode = keyAdapterMap.get(keName.toUpperCase());
        jIntellitypeInstance
                .registerHotKey(identifier, ModHotKeyEnum.getKeyCode(modifier), keycode);
        // 功能键
        modHotkeyMap.put(identifier, modifier);
        // 普通键
        hotkeyMap.put(identifier, keName);
    }


    /**
     * 删除默认注册热键 ( ctrl + c, ctrl+insert)
     */
    public void clearKey(int keyId) {
        jIntellitypeInstance.unregisterHotKey(keyId);
    }

    /**
     * 删除监听器
     */
    public void clearKeyEvent() {
        jIntellitypeInstance.removeHotKeyListener(hotkeyListener);
    }

    /**
     * 添加热键监听器
     */
    public void addKeyEvent() {
        List<Integer> keyId= Arrays.asList(1,2,3);
        hotkeyListener = (val) -> {
            if (keyId.contains(val)){
                hotkeyFunc(val);
            }
        };
        jIntellitypeInstance.addHotKeyListener(hotkeyListener);

    }

    /**
     * 热键功能 将复制的内容写入文本
     */
    private void hotkeyFunc(int keyId) {
        // 复制热键触发同时将该热键进行注销, 防止与系统热键冲突,并同时自动执行复制按键
        clearKey(keyId);
        String modeKeyName = null;
        String keyName = null;
        // ctrl + C 获取功能和普通键进行组合模拟
        if (modHotkeyMap.containsKey(keyId) && hotkeyMap.containsKey(keyId)) {
            modeKeyName = modHotkeyMap.get(keyId);
            keyName = hotkeyMap.get(keyId);

            Integer modKeyCode = keyAdapterMap.get(modeKeyName.toUpperCase());
            Integer keyCode = keyAdapterMap.get(keyName.toUpperCase());

            robot.keyPress(modKeyCode);
            robot.keyPress(keyCode);

            robot.keyRelease(modKeyCode);
            robot.keyRelease(keyCode);
        } else {
            // 默认
            Integer keyCode = RobotKeyEnum.getKeyCode(keyId);
            robot.keyPress(KeyEvent.VK_CONTROL);
            robot.keyPress(keyCode);

            robot.keyRelease(KeyEvent.VK_CONTROL);
            robot.keyRelease(keyCode);
        }
        //延时 300 ms ,防止同时执行时热键冲突
        robot.delay(300);
        cclipboardService.save2Txt(filePath);
        // 粘贴板内容复制到文本中后继续将该热键进行注册
        if (Strings.isBlank(modeKeyName) || Strings.isBlank(keyName)) {
            addKey(keyId);
        } else {
            addKey(keyId, modeKeyName, keyName);
        }
    }

}
